#include "ErrorHandler.h"
#include <deque>

namespace errors{


void ErrorHandler::setErrorCallback(std::function<void(const ErrorInfo&)> callback, bool enqueueErrors) {
    std::lock_guard<std::mutex> lock(m_callbackMutex);
    m_errorCallback = std::move(callback);
    m_enqueueErrors.store(enqueueErrors, std::memory_order_relaxed);
}


void ErrorHandler::setError(const std::string& msg, ErrorCode code, ErrorSeverity severity, const std::string& source) {
    ErrorInfo newError(msg, code, severity, source);
    ErrorInfo errorToReportForCallback = newError;

    if (m_enqueueErrors.load(std::memory_order_relaxed)) {

        std::lock_guard<std::mutex> lock(m_errorMutex);
        bool coalesced = false;

        if (!m_errorQueue.empty()) {
            ErrorInfo& lastErrorInQueue = m_errorQueue.back();


            if (lastErrorInQueue.message == newError.message &&
                lastErrorInQueue.code == newError.code &&
                lastErrorInQueue.source == newError.source &&
                lastErrorInQueue.severity == newError.severity &&
                (newError.timestamp - lastErrorInQueue.timestamp) < m_coalescingTimeWindow) {
                
                lastErrorInQueue.occurrences++;
                lastErrorInQueue.timestamp = newError.timestamp;
                errorToReportForCallback = lastErrorInQueue;
                coalesced = true;
            }
        }

        if (!coalesced) {
            if (m_errorQueue.size() >= m_maxErrorCount) {
                if (!m_errorQueue.empty()) { // 确保不为空才pop
                    m_errorQueue.pop_front();
                }
            }
            m_errorQueue.push_back(newError);
        }
    }
    callErrorCallback(errorToReportForCallback);
}


std::optional<ErrorHandler::ErrorInfo> ErrorHandler::getNextError() {
    std::lock_guard<std::mutex> lock(m_errorMutex);
    if (m_errorQueue.empty()) [[likely]] {
        return std::nullopt;
    }
    ErrorInfo error = m_errorQueue.front();
    m_errorQueue.pop_front(); // Use pop_front for deque
    return error;
}

bool ErrorHandler::hasError() const noexcept {
    std::lock_guard<std::mutex> lock(m_errorMutex);
    return !m_errorQueue.empty();
}

std::string ErrorHandler::getErrorMessage(bool removeError) noexcept {
    std::lock_guard<std::mutex> lock(m_errorMutex);
    if (m_errorQueue.empty()) [[likely]] {
        return {};
    }

    if (removeError) {
        std::string msg = std::move(m_errorQueue.front().message);  // 直接转移内容
        m_errorQueue.pop_front();  // 然后移除
        return msg;
    }

    return m_errorQueue.front().message;  // 返回 const 引用绑定的副本
}


ErrorCode ErrorHandler::getErrorCode(bool removeError)  noexcept {
    std::lock_guard<std::mutex> lock(m_errorMutex);
    if (m_errorQueue.empty()) [[likely]] {
        return ErrorCode::Success;
    }
    if (removeError) {
        ErrorCode code = m_errorQueue.front().code;
        m_errorQueue.pop_front();
        return code;
    }
    return m_errorQueue.front().code;
}

size_t ErrorHandler::getErrorCount(int level) noexcept {
    std::lock_guard<std::mutex> lock(m_errorMutex);
    if (level <= 0|| level > static_cast<int>(ErrorSeverity::Fatal)) [[likely]] {
        return m_errorQueue.size();
    }
    return std::count_if(m_errorQueue.begin(), m_errorQueue.end(), [level](const ErrorInfo& error) {
        return error.severity == static_cast<ErrorSeverity>(level);
    });
}

void ErrorHandler::clearErrors() noexcept {
    std::lock_guard<std::mutex> lock(m_errorMutex);
    m_errorQueue.clear(); // Use clear for deque
}

void ErrorHandler::callErrorCallback(const ErrorInfo& error) {
    std::lock_guard<std::mutex> lock(m_callbackMutex);
    if (m_errorCallback) [[likely]] {
        m_errorCallback(error);
    }
}


} // namespace errors
